François Beausoleil and Daniel Haran join GiraffeSoft and our new site launches! 6

Posted by james
on Friday, November 21

Let's start with the biggest news. This has been a long time in the making. At Rubyfringe, Francois, Daniel, and I had a long conversation about how great it would be if we could work together.

We gave it a shot for Rails Rumble, in which we built what does this error mean. We won for most useful, which we took as a sign that our idea of working together was a good one.

I can't express how excited I am and privileged I feel to be working with François and Daniel. They are truly top notch in every way. Their contributions to open source, previous projects, and resumes speak for themselves.

If you don't know these amazing guys, you can read about François and Daniel on our new site!

The New giraffesoft.ca

Thanks to our good friends over at Arktyp and the awesome Webby framework, we finally have a real website. With plenty of work coming in over the last 14 months or so, I was having a really hard time motivating myself to put a full fledged site together.

Well, now that the team is growing, I finally got my shit together to finish up the site. I'm really excited to be able to show off some of our past projects and open source work. We've got a full range of services products and we're finishing up an app or two that you'll hear more about soon. So, check it out. It's awesome.

This is just the beginning. There'll be some more giraffesoft announcements soon, so stay tuned.

MoR => open_source_hackfest?

Posted by james
on Tuesday, November 04

Over the last year or so, I’ve really enjoyed Montreal on Rails. There have been lots of awesome presentations, and general good times had by all.

When Carl asked for feedback on Uservoice, a lot of people seemed interested in more presentations geared towards newbies. While presentations can be really interesting and useful, most of the best programmers I know learned their craft through open source work. There’s no better way to improve your skills (not to mention your profile in the industry).

So, I’ve been thinking about organizing a monthly, open source hackfest.

It would be an informal evening where people could come and work on FLOSS. If you have a project, it would be a great place to get help from some of your local ruby gurus, or just an excuse to work on your project. If not, it’d be a great place to pick up a project and learn from other developers.

At the end of every evening, we could have a few lightning talks (5mins), to give people the opportunity to show off what they’ve been working on. Or not, if nobody wants to speak. Only rule: no preparation allowed. No slides. Nothing.

Think of it sort of like Zed Shaw’s Freehacker’s Union, minus the hazing ritual for new members.

So, what do you think? If we turned MoR in to an open source hack fest for a couple of months, would you miss the presentations? Is this something you’re interested in trying out? Will you be offended if we open it up to all things Ruby, instead of just rails?

Please direct your comments to the post on the MoR blog.

Off-Topic: Café Myriade 4

Posted by james
on Monday, October 27

I'm a coffee geek. About half my kitchen is dedicated to espresso gear, and various tools for brewing filtered coffee, including a vacuum pot, and the newest addition, a cafe solo. Anyway, being a coffee geek, I also hang out with coffee geeks. And, it just so happens that the guy who taught me everything I know about coffee, competitive barista Anthony Benda, just opened his very own cafe.

If you like coffee, you owe it to yourself to check this place out. There's a huge difference between the crapstuff you get at starbucks (which we lovingly refer to as 'dirty water'), or even your local coffee shop, and what they're brewing over at Myriade.

The rest of this article is cross-posted from Daniel Haran's blog.

Daniel and I went to visit Cafe Myriade (praized page) for their Grand Opening. He grabbed this shot after a friendly latte art challenge:

Latte Art at Cafe Myriade

Myriade is worth visiting if you care about either coffee or chocolate. Baristas Anthony Benda and Scott Rao are both obsessive about coffee: Anthony is a competitive barista and Scott is the author of The Professional Barista’s Handbook.

Seeing them at work refining techniques and recipes is amazing and inspiring; they had received a new type of coffee maker akin to a french press and were testing different quantities and steep times.

For chocolate fanatics this is the only retail spot I know of in Montreal that carries SOMA chocolate, including their hot chocolate. SOMA is one of only 2 chocolatiers in Canada that make their own chocolate; I religiously visit them every time I’m in Toronto.

One of Anthony’s signature drinks is a coffee with melted chocolate. For his last competition he tried over a dozen different chocolates to find the perfect fit. Rather than being satisfied with his choice, it only seems to have ignited another obsession.

Cafe Myriade is located at 1432 Mackay, close to Maisonneuve at Guy-Concordia.

Our Rumble App: What Does this Error Mean? 2

Posted by james
on Sunday, October 19

Francois, Daniel, and I (and Mat, in spirit) spent the weekend rumbling. It was a great time coding with these two superstars, but you don't care about that.

Our app is called what does this error mean?. We all see error messages, and until now, the best way to look for solutions to those error messages was doing a google search. The problem with google searches, though, is that the results are ordered by the quality of the site, not by the quality of the solution. What does this error mean solves that problem, and a few more.

But, really, reading sucks. So, watch our screencast to learn all about wdtem.

Rails & Merb Integration

As part of our rumble project, we built plugins for both rails and merb that override their default development mode error messages. With our plugin installed, you'll see our logo below the error message. Simply click on the logo to automatically jump to a what does this error mean search!

For rails:

$ script/plugin install git://github.com/giraffesoft/what_does_this_error_mean-rails.git

For merb:

sudo gem install what_does_this_error_mean-merb

Please Vote for Us!

If you think our app is cool, please consider voting for us once rails rumble voting starts! We don't know the url yet, but have been told to point people to our team page.

Watch François Beausoleil Train for Rails Rumble 2

Posted by james
on Wednesday, October 15

My Rails Rumble team is all set to win, because we trained the hardest. Check out the video François made of some of his hard work preparing for the competition.


RailsRumble 2008 Training from François Beausoleil on Vimeo.

Blank: A Starter App for r_c and shoulda Users 17

Posted by james
on Thursday, October 09

Bort was released recently. Peter Cooper speculated that "...it could well catch on as the de facto bare bones / generic Rails application". But, what about us non-RSpec users? There are dozens of us, I tell you. Dozens!

We build a lot of apps at GiraffeSoft — we love to experiment with whatever ideas excite us on any given day. We're all sick of editing restful_auth code, and moving tests over to Shoulda and the one assertion per test pattern. Bort doesn't suit our needs. So, blank was born.

Right now, it's pretty simple. It has authentication, and forgot password. That's about it. But, it's no biggie. Since blank creates your new app as a git repo that shares history with blank's repo, you can pull in changes we make at any time. So, when we finally get around to implementing openid support, you'll get it for free, if you start with blank.

Vendored

All of our standard tools (and rails) are vendored:

  • active_presenter
  • andand
  • attribute_fu
  • hoptoad
  • mocha
  • rake
  • restful_authentication
  • ruby-openid
  • will_paginate

Installation

Installing blank is as easy as running a rake task. Except that blank uses thor instead, because it’s the new hotness, and it supports remote tasks.

Just install thor:

$ sudo gem install thor

…then install blank’s thor tasks:

$ thor install http://github.com/giraffesoft/blank/tree/master%2Fthorfiles%2Fblank.thor?raw=true

…then you’re ready to create a new app with blank:

$ thor blank:new_app the_name_of_my_app the@git.repo.it.will.live.in

That’s it! The thorfile will display a couple of rake notes where you should replace blank app with your app's name. Also, you'll want to fill in your hoptoad API key in config/initializers/hoptoad.rb.

If we improve the thor file, all you have to do is run:

$ thor update blank

before creating your next app, and you’ll get the changes automagically.

Development

All development will be done at the github repo. Fork away :)

Credits

Blank was created by me, with contributions from Daniel Haran.

resource_controller 0.5 2

Posted by james
on Wednesday, September 03

I've been really bad about releasing new versions of r_c. The last version that I actually released officially was 0.2. Well, enough has happened that it's time to get official about things.

What's New

  • Singleton controllers are now supported, thanks to Bartek Grinkiewicz (grin). Just inherit from ResourceController::Singleton, and you'll get a set of default action options that makes sense for a singleton controller. As always, there's more info in the RDoc.
  • It's possible to properly inherit from r_c controllers now. However, you have to use the declaration syntax (calling resource_controller in your controller's class definition, rather than inheriting from RC::Base) to make it all work right.
  • The flash helper now accepts a block, which means that you can interpolate in your flash messages. (i.e. create.flash { "#{@post.title} successfully created!" })
  • Thanks to Jonathan Barket (his github is here), the scaffold_resource now generates RSpec specs, if RSpec is installed in your app.
  • Lots of bugs and little issues were fixed.
  • All r_c development is officially moved to github. Follow the repo here, if you're not already.
  • From now on, r_c will only be supported as a gem dependency. Gem plugins are the new hotness; love them.

Contributors

Lots of awesome people contributed to this release.

Spree

As I mentioned before, Spree, the "Open Source Commerce Platform for Ruby on Rails", has moved to r_c. That also means that the Rails Envy guys' awesome new screencast site Envy Casts is powered by r_c. Since spree is open source, it makes a great example app for r_c. If you're looking for examples, the Spree source is a great place to start.

Get It

Add it as a gem dependency:

config.gem 'resource_controller'

Install it as a gem manually:

$ sudo gem install resource_controller

Or grab the source:

$ git clone git://github.com/giraffesoft/resource_controller.git

As always, the RDoc is available at http://jamesgolick.com/resource_controller/rdoc/index.html.

Rails commerce platform Spree moves to resource_controller 0

Posted by james
on Tuesday, August 12

Spree wanted to become RESTful, so they chose resource_controller to help them keep DRY. At least some of those changes now seem to be merged in to master.

Wearing Out My Delete Key 20

Posted by james
on Monday, August 04

One of the great things about pair programming is getting to see how somebody else approaches a problem. One can learn a lot by observing another programmer's thought process. For example, the first day of working with Mat, I learned that some programmers use something called a 'debugger' to troubleshoot problems in their code.

Jokes aside, I think every programmer should take every pairing opportunity they get. This article is about a realization I had while pair programming with Daniel Haran on the way to RubyFringe.

Evidently, not everybody is quite as hard on their delete key as I am.

Always Delete

At one point during the train ride, Daniel looked at me, and said, "Wow — we're deleting more code than we're keeping!" To which I responded, "Yeah, of course we are. Don't you always?"

This illustrates one of my strategies for writing great code. Trying to get it right the first time is futile. So, I stopped trying.

I'd much rather get it out of my brain, and in to my editor, no matter how crude; see my tests go green, and refactor it immediately. Mostly, that means deleting the entire implementation, and starting from scratch. Let me tell you why.

Speculating Sucks

Trying to perfect an implementation in one's mind is a form of speculation. It is extremely difficult to judge the readability of something you cannot read, or the performance of something you cannot run. Such a judgement may be possible in some cases, but it will never be a replacement for actually seeing, reading, or running the code.

A good portion of the time, the solution that seems crude in my mind turns out to be perfectly adequate once I see it in my editor. Sometimes, it's even fairly elegant. When my first try sucks, refactoring leads me to the right solution far more quickly than speculating ever could. This is because identifying problems in my initial implementation is so much easier when I can actually see, and manipulate it.

A great programmer certainly has a better sense for which solutions are going to be more readable. That programmer will usually get closer on the first try. But, in my experience, the very best programmers are the fastest at trying out several different solutions and choosing between them, or quickly iterating on one, until it's perfect.

Exponential Productivity

The elegant implementation you see when you read a great programmer's code is often the third or fourth try. The great programmer is often more effective because they can implement several solutions in the same amount of time it takes the average programmer to implement one.

All the while, they are improving their base of experience by having real interactions with many real solutions to the same problem. That allows them to arrive at a better solution to the problem next time. That, I believe, is one of the reasons programmer productivity is exponential.

Conclusions

Since I started working with highly productive languages like Python and Ruby, I have come to believe that code should be disposable. The easier it is to refactor, or even rewrite (a form of refactoring), the better. That's one of the reasons I am a proponent of dense languages. Anything that can't be easily refactored due to its size is a major liability.

It seems pretty clear to me that programming is best learned through doing. That's why so many philosophy graduates, and jazz musicians are better programmers than unmotivated kids with software engineering degrees. Writing code is a lot more valuable than thinking about code.

The faster you can write, and evaluate code, the faster you can get better, which accelerates your ability to write and evaluate code. That's exponential growth.

Tweet From the Command Line 9

Posted by james
on Thursday, July 31

I'm a command line junkie. I crave the command-line like addicts crave heroin. Okay, maybe a little bit less.

In an effort to spend more time on the command-line, and less time in my web browser, I created a little utility that allows me to tweet from the prompt. I call it tweet.

It's going to make me more productive. So, now I won't have to feel bad about twitter's victory. It will make you more productive too.

You use it like this:

$ tweet "I'm going to walk my dog."

You download it like this:

$ sudo gem install giraffesoft-tweet

You fork it from here.

See the README for the config file syntax.

That is all.

Introducing ActivePresenter: The presenter library you already know. 22

Posted by james
on Sunday, July 27

Presenters were a hot topic in the rails community last year. A lot of prominent bloggers wrote about using them, and the implementations they had come up with. Oddly, though, when I needed one a couple of weeks ago, I was unable to find a suitable implementation. Lots of articles — no code.

Let's answer the question on everybody's mind before we move on. Feel free to skip ahead if you already know the answer.

WTF is a presenter?!

In its simplest form, a presenter is an object that wraps up several other objects to display, and manipulate them on the front end. For example, if you have a form that needs to manipulate several models, you'd probably want to wrap them in a presenter.

Indeed, attribute_fu solves this problem for some cases. However, when you're dealing with unrelated models, or, really, any situation other than a parent saving its children, you're probably better off using a presenter.

Presenters take the multi model saving code out of your controller, and put it in to a nice object. Because presenter logic is encapsulated, it's reusable, and easy to test.

Want one?

ActivePresenter

Daniel and I wrote most of this on the train ride over to RubyFringe. It is an ultra-simple presenter base class that is designed to wrap ActiveRecord models (and, potentially, others that act like them).

ActivePresenter works just like an ActiveRecord model, except that it works with multiple models at the same time. Let me show you.

Imagine we've got a signup form that needs to create a new User, and a new Account. We'd create a presenter that looks like this.

class SignupPresenter < ActivePresenter::Base
  presents :user, :account
end

Then, we'd write a new action like this one:

def new
  @signup_presenter = SignupPresenter.new
end

And a form:

<%= error_messages_for :signup_presenter %>

<%- form_for @signup_presenter, :url => signup_url do |f| -%>
  <%= f.label :account_subdomain, "Subdomain" %>
  <%= f.text_field :account_subdomain %>
  <%= f.label :user_login, "Login" %>
  <%= f.text_field :user_login %>
<%- end -%>

A create action:

def create
  @signup_presenter = SignupPresenter.new(params[:signup_presenter])
  
  if @signup_presenter.save
    redirect_to dashboard_url
  else
    render :action => "new"
  end
end

Lastly, an update action:

def update
  @signup_presenter = SignupPresenter.new(:user => current_user, :account => current_account)
  
  if @signup_presenter.update_attributes(params[:signup_presenter])
    redirect_to dashboard_url
  else
    render :action => "edit"
  end
end

Seem familiar?

If you're using r_c, most of this comes for free with:

class SignupsController < ResourceController::Base
  model_name :signup_presenter
end

For more on complex forms in rails, and the presenter pattern, see my upcoming PeepCode screencast!

Organization

I have been sticking my presenters in app/presenters. If you want to do the same, you'll need to add a line like this to your environment.rb:

config.load_paths += %W( #{RAILS_ROOT}/app/presenters )

Get It!

As a gem:

$ sudo gem install active_presenter

As a rails gem dependency:

config.gem 'active_presenter'
Or get the source from github:
$ git clone git://github.com/giraffesoft/active_presenter.git

(or fork it at http://github.com/giraffesoft/active_presenter)

Also, check out the RDoc.

Okay Twitter, You Win. 2

Posted by james
on Thursday, July 17

For the longest time, I've been telling myself that I'm going to stop using twitter. It's a waste of time, and I was just trying it out anyways.

Well, something keeps drawing me back to it. I keep tweeting. So, I've given in.

I actually spent some time styling my twitter page to look giraffesoftish. I even put the badge on my blog (to your right, underneath github).

Let this blog post serve as the (reluctant) official notice that I am on twitter. Follow me here.

Business Logic Bleeding in to Views and Controllers 7

Posted by james
on Wednesday, July 16

I've been doing a fair bit of training recently — both while bringing Mat up to speed on the latest and greatest best practices, and going and speaking to clients' teams. A few concepts keep coming up, so I'm going to try to blog about them as they do. Here's the first one.

I see this all over client projects, and admittedly, some of my older ones:

<%- if @post.creator == current_user -%>
  <%= link_to "Edit", edit_post_path(@post) %>
<%- end -%>

Seems innocuous — the post can only be be edited by its creator. But, that is a business logic rule, so it belongs in your model (and your tests).

context "Posts" do
  setup do
    @creator      = create_user
    @post         = @creator.posts.create!(hash_for_post)
    @another_user = create_user
  end

  should "be editable by their creator" do
    assert @post.can_be_edited_by?(@user)
  end
  
  should "not be editable by another random user" do
    assert !@post.can_be_edited_by?(@another_user)
  end
end
class Post < ActiveRecord::Base
  def can_be_edited_by?(user)
    user == creator
  end
end

Why? A few reasons. First, because your model classes should represent a complete picture of your data's structure, and business logic rules. Second, a rule like that deserves testing, even if it's as simple as the one in this example. Finally, because later on, you might want admins to be able to edit posts, too.

context "Posts" do
  setup do
    @creator      = create_user
    @post         = @creator.posts.create!(hash_for_post)
    @another_user = create_user
    @admin        = create_user :admin => true
  end

  should "be editable by their creator" do
    assert @post.can_be_edited_by?(@user)
  end
  
  should "be editable by an admin" do
    assert @post.can_be_edited_by?(@admin)
  end
  
  should "not be editable by another random user" do
    assert !@post.can_be_edited_by?(@another_user)
  end
end
class Post < ActiveRecord::Base
  def can_be_edited_by?(user)
    user == creator || user.admin?
  end
end

If we're using the can_be_edited_by? method all over our controllers and views, a change to the access policy shouldn't entail anything other than editing a couple of lines of code in our models and unit tests.

Subtler

Here's another one I see all the time (especially in my code). This one tends to be harder to spot.

class MessagesController
  before_filter :login_required
  
  protected
    def project
      @project ||= current_user.projects.find(params[:project_id])
    end
  
    def messages
      project.messages.find(:all)
    end
end

The idea here is that we're using the association as an implicit access control mechanism. If the user row is associated with the project row, the user has access to that project. I know that there are several r_c users who have used this pattern, since it's so easy to implement with r_c. I've even recommended it. Ouch.

The problem with this pattern is lack of encapsulation. There are a good handful of situation in which you might want the access rule to change such that you'd have to go and change every call to current_user.projects. Which is ugly.

What if you decided to make ProjectMembership a join model, for example? Rather than actually deleting membership rows, you decide you'd like, for record keeping purposes, to have a revoked_at field which denotes a former membership made invalid. You might think — no problem, I can just change the conditions of the association.

class User
  has_many :projects, :through => :project_memberships, :conditions => "project_memberships.revoked_at IS NULL"
end

Aside from ambiguous naming, this remains an incomplete solution. At some point, you're going to decide that admins have access to all projects. You could add that condition to your SQL, too, but that approach is problematic for the same reason we're talking about, here: the definition of an admin may change. So, we need a different strategy.

class Project
  has_many :project_memberships
  has_many :users, :through => :project_memberships
  
  named_scope :with_active_membership_for, lambda { |user| { :include => :project_memberships, :conditions => ['project_memberships.user_id = ? AND project_memberships.revoked_at IS NULL', user.id] } }
  
  def self.for(user)
    user.admin? ? self : self.with_active_membership_for(user)
  end
end

This isn't a perfect solution, since the definition of a revoked membership is living in the SQL; ideally that would be defined in ProjectMembership. But, with a join model, I'm not sure of any other way. So, at least in this instance, we can use the Project.for method in our controllers, and views, and not have to worry about a change in the project access rules causing a need for major refactoring later on.

class MessagesController
  before_filter :login_required
  
  protected
    def project
      @project ||= Project.for(current_user).find(params[:project_id])
    end
  
    def messages
      project.messages.find(:all)
    end
end

But, Not Always

One could look at these examples and decide to engage in reductio ad absurdum. Why not encapsulate the messages collection, they'd ask?

The rule I tend to stick to is that if I know that there's any kind of access control policy being enforced on an object or collection, it gets encapsulated, and tested in the model.

In the fictional examples above, the assumption was that provided access to the project, a user would be allowed to access all of messages within. In that case, I wouldn't have encapsulated, because there would have been no rule to encapsulate.

As soon as there is a policy, though, it belongs in tested methods in your models.

The controller's responsibility in all of this is to control access to a resource in the sense that it actually performs the check, and redirects the user to a login screen, or shows an access denied message if they are not entitled to perform said action on said resource. The controller is not, however, responsible for deciding who it is that gets access; that's the model's job.

Like a bouncer at the door of a nightclub, your controller shouldn't make the rules, it should only enforce them. Luckily for you, cute 17 year old girls won't have the same effect on your controller that they might on a bouncer.

Mat Martin Joins GiraffeSoft! 1

Posted by james
on Monday, July 07

Mat has been a staple at Montreal on Rails since day one. Hanging out with him was always fun; we had a ton of interesting conversations. Whether we were discussing testing frameworks, or debating the latest raganwald post, chatting with Mat was always interesting, and fun. We hung out a lot at CUSEC, which is when Mat told me about his C# job — he wasn't... ummm.... loving it. That's when I started devising my plan to hire him, but alas, it wasn't time. Fast forward a couple of months, and finally, it is time!

But, enough about me, here are some fun facts about Mat.

  • Mat is a language geek. His presentations at MoR have been about JRuby, and rubinius. He can often be found reading Steve Yegge, and Raganwald. Don't be surprised if Mat leaves GiraffeSoft at some point in the future to escape from "ruby hell" for the purity of lisp.
  • Mat *really* loves testing. ...so much that at a former job where testing wasn't part of the culture, Mat wrote his code test first, and then trashed the tests when he checked in his code, since he wasn't allowed to check them in. He'll fit right in here :).

What Mat'll be Working On

As far as client work is concerned, Mat will be working on a couple of stealth mode projects that we'll hopefully be able to blog about in a couple of months. Client work, however, will only account for around 50% of Mat's time. So, what about the other half?

I'm going to try something totally crazy: 50% time. Yeah, that's right, fifty percent time, 5-0 — eat your heart out, google. Mat will have half his time to work on whatever he wants. He may use his time for blogging, working on Giraffetyp projects, open source, or developing some of his own ideas. Investing time and effort in some of my ideas, and open source projects has been a huge win for my skill set, and profile, and I'm taking a serious bet that it'll do the same for Mat.

So, Look Out

Mat has already proven himself to be a great blogger, and launched his first open source project. Nearly every article he's written over the last few months has been featured on programming reddit, hacker news, etc. His first open source project even got a shout outs from the github blog, and the rails envy podcast. Armed with ample time every week to work on that stuff, I'm betting Mat will become a prominent figure in the community in no time.

Here's what Mat has to Mat has to say about his move.

r_c, meet RSpec 2

Posted by james
on Friday, June 20

Jonathan Barket just sent me a patch that gets resource_controller's scaffold_resource generator to spit out RSpec specs! I quickly merged it in to master, and wanted to announce it to the world, since it's something I've been hoping to get added to the plugin for a while.

r_c's scaffold_resource generator now supports vanilla test/unit, Shoulda, and RSpec for tests, and erb, and haml for templating. It will sense which of those plugins or gems you have installed in your app, and generate accordingly — it's absolutely 0 configuration.

So, if you're an RSpec user, grab the latest master from github, and get generating! :)


Clicky Web Analytics